<?php

namespace app\devices\command;

use app\data\service\UserService;
use app\devices\service\DevicesService;
use app\devices\service\OrderService;
use think\admin\Command;
use think\admin\Exception;
use think\cache\driver\Redis;
use think\console\Input;
use think\console\Output;

/**
 * 自动检测订单
 * Class CheckDevice
 * @package app\data\command
 */
class CheckOrder extends Command
{
    protected $redis;

    protected function configure()
    {
        $this->setName('xdevice:CheckDeviceOrder');
        $this->setDescription('检测订单的各种状态');
        $this->redis = new Redis();
    }

    /**
     * 业务指令执行
     * @param Input $input
     * @param Output $output
     * @return void
     * @throws Exception
     */
    protected function execute(Input $input, Output $output)
    {
        $this->_autoSetTimeOutOrder();
        $this->_autoTimeOutOrder();
        $this->_autoPushTimeOutOrder();
    }

    private function _autoSetTimeOutOrder(){
        $stores = DevicesService::instance()->getStoresEndHours2();
        if(count($stores)){
            $map = [
                ['status', '=', 1],
                ['create_time', '>', strtotime(date('Y-m-d'))],
                ['store_id', 'in', array_keys($stores)]
            ];

            $orders = $this->app->db->name("jcg_devices_order")->where($map)->column("id, store_id, user_id, money, extends, create_time, out_times");

            $out_order = [];
            foreach ($orders as $row){
                $times = strtotime(date("Y-m-d ".substr($stores[$row['store_id']],0,5), $row['create_time']));
                if($times<=time() && $row['out_times']<1){
                    $out_order[] = $row['id'];
                }
            }

            if($out_order) {
                $this->app->db->name("jcg_devices_order")->where("id", "in", $out_order)->update(['out_times'=>1]);
            }
        }
    }

    /**
     * 超时订单提醒
     * @throws Exception
     */
    private function _autoTimeOutOrder()
    {
        try {
            $stores = DevicesService::instance()->getStoresEndHours();
            if(count($stores)){
                $map =  [
                    ['status', '=', 1],
                    ['create_time', '>', strtotime(date('Y-m-d'))],
                    ['store_id', 'in', array_keys($stores)]
                ];

                $redis_pushs = $this->redis->get("PushTimeOutOrder");
                if($redis_pushs){
                    $ids = [];
                    foreach ($redis_pushs as $row){
                        foreach ($row as $item){
                            $ids[] = $item['order_id'];
                        }
                    }
                    $map[] = ['id', 'not in', $ids];
                }

                $orders = $this->app->db->name("jcg_devices_order")->where($map)->column("id, store_id, user_id, money, extends, create_time, out_times");
                if($orders){
                    $pushs = [];
                    foreach ($orders as $row){
                        $items = [];
                        $times = strtotime(date("Y-m-d ".substr($stores[$row['store_id']],0,5), $row['create_time']));
                        foreach([30, 10, 0] as $key=>$val){
                            $tt = $val>0?strtotime("-".$val.' minute', $times):$times;
                            if($tt-60<time()){
                                continue;
                            }
                            $items['order_id'] = $row['id'];
                            $items['item'][] = [
                                'times'=>$tt,
                                'key'=>$key,
                                'extends'=>$row['extends'],
                                'money'=>$row['money'],
                                'end_hour'=> $times,
                            ];
                        }
                        $pushs[$row['user_id']][] = $items;
                    }
                    if($pushs) $this->redis->set("PushTimeOutOrder", $pushs, 75*60);
                }
            }
        } catch (\Exception $exception) {
            echo $exception->getLine();
            var_dump($exception->getMessage());
//            $this->queue->error($exception->getMessage());
        }
    }

    private function _autoPushTimeOutOrder(){
        $keys = 'PushTimeOutOrder';
        try {
            $list = $this->redis->get($keys);
            $uservice = new UserService($this->app);
            if(empty($list)) return true;
            $m_list = [];
            foreach ($list as $user_id=>$items){
                if($items){
                    $openid = $uservice->getOpenid($user_id);
                    $m_times = [];
                    if($openid){
                        $first_title = ['您好，您的寄存柜订单还有30分钟到期，请及时取出物品。', '您好，您的寄存柜订单还有10分钟到期，请及时取出物品。', '您好，您的寄存柜订单已超时，请联系柜点工作人员。'];
                        foreach ($items as $k=>$v){
                            $item = [];
                            if($v['item']){
                                foreach ($v['item'] as $val){
                                    if(time()>=$val['times']){
                                        $extends = json_decode($val['extends'], true);
                                        OrderService::instance()->sendTemp(3, $openid, [$extends['device_name'], ($extends['box_num']<10?'0'.$extends['box_num']:$extends['box_num']).'号', date("Y-m-d H:i", $val['end_hour'])], $first_title[$val['key']],'请在规定的营业时间内取包，超时未取包，请联系：'.($extends['store_contact']??''));
                                    }else{
                                        $item[] = $val;
                                    }
                                }
                                $m_times[] = [
                                    'order_id'=>$v['order_id'],
                                    'item' => $item,
                                ];
                            }else{
                                $m_times[] = [
                                    'order_id'=>$v['order_id'],
                                    'item' => $item,
                                ];
                            }
                        }
                    }
                    if($m_times) {
                        $m_list[$user_id] = $m_times;
                    }
                }else{
                    $m_list[$user_id] = [];
                }
            }
            $this->redis->delete($keys);
            if($m_list) $this->redis->set($keys, $m_list, 60*60);

            unset($list, $times, $m_times, $m_list);
        }catch (\Exception $e){
            echo $e->getLine().PHP_EOL;
            var_dump($e->getMessage());
        }

    }
}